﻿using blackhouse.Aparts.Web;
using blackhouse.BlackApart.Business;
using blackhouse.BlackApart.Business.Apartments;
using blackhouse.BlackApart.Business.ApartmentServices;
using blackhouse.BlackApart.Business.Prices;
using blackhouse.BlackApart.Business.Reservations;
using blackhouse.BlackApart.Web;
using blackhouse.BlackApart.WebNemo;
using blackhouse.mojoPortalExtend;
using blackhouse.StareKino.Web.InstallScripts;
using blackhouse.StareKino.Web.Modules;
using blackhouse.WebNemo.Business.Groups;
using blackhouse.WebNemo.Web;
using blackhouse.WebNemo.Web.Controls;
using mojoPortal.Web;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace blackhouse.StareKino.Web {
    public partial class Apartments : OwnedNonCmsBasePage {

        #region Fields

        private Factory factory = Factory.Instance();
        private SearchState queryState = SearchState.GetFromContext();
        private IApartmentGroup[] groups;

        #endregion

        #region PageLifeCycle Handlers

        protected override void OnPreInit(EventArgs e) {
            base.OnPreInit(e);

            InstallCinemaDatabase.Install();
        }

        protected override void OnLoad(EventArgs e) {
            base.OnLoad(e);
            this.SetScenario();
            this.PopulateControl();

            this.SetPageSettingsFromCms();
        }

        #endregion

        #region Methods

        private void SetScenario() {
            if (this.queryState.IsSet) {
                FreeApartments search = new FreeApartments(this.queryState.ArrivalDate, this.queryState.DepartureDate, this.queryState.PeopleCount);
                List<IApartmentGroup> gr = new List<IApartmentGroup>();
                if (search.Count() > 0) {
                    for (int xv = 0; xv < search.Count(); xv++) {
                        gr.Add(new ApartmentGroupWithVariant(
                        search.ElementAt(xv).GetGroups().OrderByDescending(g => g.NumberOfPeople).First(),
                        search.ElementAt(xv)));
                    }
                }
                //if (this.queryState.PeopleCount > 1) { // szukamy apartamentów z liczbą osób równą PeopleCount - 1 oraz z dostawką
                //    FreeApartments searchWitchExtraBed = new FreeApartments(this.queryState.ArrivalDate, this.queryState.DepartureDate, this.queryState.PeopleCount - 1);
                //    if (searchWitchExtraBed.Count() > 0) {
                //        IAdditionalService services = Factory.Instance().GetAdditionalService();
                //        for (int xveb = 0; xveb < searchWitchExtraBed.Count(); xveb++) {
                //            Variant v = searchWitchExtraBed.ElementAt(xveb);
                //            IApartmentGroup group = v.GetGroups().FirstOrDefault(g => g.NumberOfPeople == this.queryState.PeopleCount - 1);
                //            if (group == null) continue;
                //            IAdditionalService extraBedService = services.FindService(group.Id, "extrabed");
                //            if (extraBedService != null) {
                //                gr.Add(new ApartmentGroupWithVariantAndExtraBed(group, v, extraBedService));
                //            }
                //        }
                //    }
                //}
                this.groups = gr.ToArray();
            } else
                this.groups = factory.GetApartmentGroup().GetAllApartmentTypes();
        }

        private void PopulateControl() {
            this.bhSorterControl.AddSorter("price", GetGlobalResourceObject("Apartments", "price").ToString(), SortByPrice, BlackApart.Business.ApartmentSortModel.SortDirection.Asc);
            this.rptApartments.DataSource = this.GetRepeaterDataSource();
            this.rptApartments.DataBind();

            if (this.rptApartments.Items.Count == 0)
                this.pnlNoFree.Visible = true;

            if (WebNemo.Business.Factory.Instance().GetCurrentUser().HasSufficientPermissions(false)) {
                this.pnlActionLinks.Visible = true;
                using (StringWriter sw = new StringWriter())
                using (HtmlTextWriter writer = new HtmlTextWriter(sw)) {
                    writer.RenderBeginTag(HtmlTextWriterTag.Ul);
                    this.WriteListItem(writer, "Edytuj apartamenty", new NewGroupRecord("TYP_APARTAMENTU"), "double");
                    GroupRecords groupRecords = new GroupRecords("WSPOLNIE_TYP_APARTAMENTU");
                    foreach (GroupRecord gr in groupRecords) {
                        this.WriteListItem(writer, "Edytuj wspólne dane dla: " + gr.GetString("nazwa"), gr);
                    }
                    writer.RenderEndTag();
                    this.ltlActionLinks.Text = sw.ToString();
                }
            }
        }

        private void WriteListItem(HtmlTextWriter writer, string name, GroupRecord record) {
            this.WriteListItem(writer, name, record, String.Empty);
        }

        private void WriteListItem(HtmlTextWriter writer, string name, GroupRecord record, string extraClass) {
            if (!String.IsNullOrEmpty(extraClass))
                writer.AddAttribute(HtmlTextWriterAttribute.Class, extraClass);
            writer.RenderBeginTag(HtmlTextWriterTag.Li);

            writer.AddAttribute(HtmlTextWriterAttribute.Class, "ico");
            writer.RenderBeginTag(HtmlTextWriterTag.Span);
            writer.RenderEndTag();

            NemoUrl nemoUrl = new NemoUrl(NemoUrlView.RecordList);
            nemoUrl.GroupId = record.GetGroup().Id;
            if (record.RecordId > 0) {
                nemoUrl.RecordId = record.RecordId;
                nemoUrl.View = NemoUrlView.EditRecord;
            }
            writer.AddAttribute(HtmlTextWriterAttribute.Href, nemoUrl.GetUrl());
            writer.RenderBeginTag(HtmlTextWriterTag.A);
            writer.Write(name);
            writer.RenderEndTag();

            writer.RenderEndTag();
        }

        private object GetRepeaterDataSource() {
            if (this.groups.Length > 1) {
                IEnumerable<IApartmentGroup> g = this.bhSorterControl.Sort(this.groups);
                return g;
            } else
                return groups;
        }

        protected IEnumerable<IApartmentGroup> SortByPrice(IEnumerable<IApartmentGroup> groups) {
            if (this.queryState.IsSet) {
                return groups.Cast<ApartmentGroupWithVariant>().OrderBy(gv => gv.Variant.Price.GetPrice());
            } else {
                Dictionary<int, double> prices = this.GetPromoPrices();
                var q = from g in groups
                        join p in prices on g.Id equals p.Key
                        orderby p.Value
                        select g;
                return q;
            }
        }

        private Dictionary<int, double> GetPromoPrices() {
            Dictionary<int, double> prices = new Dictionary<int, double>();
            foreach (IApartmentGroup group in this.groups) {
                IApartmentPrice p = factory.GetApartmentGroupPrice(group);

                double price = 0;
                if (this.queryState.IsSet) {
                    p.ReservationFromDay = this.queryState.ArrivalDate;
                    p.ReservationToDay = this.queryState.DepartureDate;
                    p.ReservationNumberOfPeoples = this.queryState.PeopleCount;
                    price = p.GetPricePerNight();
                } else
                    price = p.GetPromoPriceFrom(group);
                prices.Add(group.Id, price);
            }
            return prices;
        }

        protected void rptApartments_ItemDataBound(object sender, RepeaterItemEventArgs e) {
            switch (e.Item.ItemType) {
                case ListItemType.AlternatingItem:
                case ListItemType.Item:
                    IApartmentGroup group = e.Item.DataItem as IApartmentGroup;
                    ApartmentGroupWithVariant groupWithVariant = group as ApartmentGroupWithVariant;
                    if (group != null) {
                        ApartmentGroupLine line = e.Item.FindControl("bhGroupLine") as ApartmentGroupLine;

                        if (line != null) {
                            if (groupWithVariant != null)
                                line.PopulateControl(group, groupWithVariant.Variant);
                            else
                                line.PopulateControl(group);
                        } else
                            e.Item.Visible = false;
                    } else
                        e.Item.Visible = false;
                    break;
            }
        }

        #endregion

    }
}